容器技術的核心在於使用 Namespace 進行隔離的進程,而 Kubernetes Pod 就是在同一個 Namespace 的容器組,不論這個容器組是單個容器還是多個容器。
應用程式是什麼?單個容器以及多個容器
Borg 是 Google 內部的早期容器管理系統,提供了兩種不同層級的資源分配概念:Borg Alloc 和 Borg Task。Borg Alloc 代表一組資源的分配單位,通常用於分配一個或多個容器所需的計算資源,比如 CPU、記憶體等。這讓多容器應用程序可以靈活運行在同一個分配區間中。相對應地,Borg Task 則是更細粒度的單元,也是 Borg 中最小的排程單位,通常用於執行單個容器的任務。Borg Task 可以直接映射到一個應用程式,但隨著多容器應用需求的增加,Borg Task 的單容器部署模式顯得靈活性不足,促使了 Borg Alloc 的發展,用來應對多容器應用場景的複雜性。這種資源分配策略為後來的 Kubernetes Pod 概念奠定了基礎。
Google 在開發容器管理系統的過程中,發現應用程式跟容器之間的關係不一定是 1:1 關係,雖然第一代系統 Borg,允許用 Borg Alloc 將一個應用程式對應多個容器,但是 Borg 並沒有強制要使用 Borg Alloc 排程應用程式,由於大多數的情況下應用程式跟容器的關係都是 1:1,所以 Borg 允許直接用 Borg Task 部屬單個容器的應用程式。
然而,單容器架構的應用程序與多容器架構之間的靈活性不足會導致管理上的不一致。應用程式可能會以不同形式進行部署,這種形態也可能隨著需求改變。例如:
比如說兩個例子:應用程式原本會自己把日誌推送到遠處的日誌管理系統,但是現在日誌系統正在重構,所以可以起一個 sidecar 攔截推送的日誌,把它轉向新的日誌管理系統,這時候的應用程式,就從單個容器變成多個容器。日誌管理系統重構完,變動程式碼之後,我們又移除 sidecar 容器,這時候的應用程式,又從多個容器變成單個容器。
第二個例子是網路:由於容器的網路通訊依賴在核心上,但是核心網路有可能 leak,因此要用 mTLS 雙向加密,所以上了 Service Mesh Sidecar 提供 mTLS,但是 sidecar 要在 userspace 處理網路,開銷太大,因此,轉用 Cillium 提供 mTLS 加密,移除原本處理網路加密的 sidecar,這也是一個多變單的過程。
在實務上,這兩個變動可能是同時發生的,因為網路以及日誌的架構,可能是由不同團隊負責,所以很有可能會在各種架構下變動。
這樣的需求,如果在 Borg 需要滿足,有可能會變成 Borg Task → Borg Alloc → Borg Task 這樣的轉換,造成複雜度,這樣的設計,不夠彈性,沒辦法處理應用程式的變化。
Borg 的架構設計難以應對這樣的動態變化。而 Kubernetes 通過 Pod 的概念解決了這個問題,將單容器和多容器的管理統一在一個框架之下。Pod 可以容納多個容器,這些容器共享同一個 Network Namespace,並通過 Loopback 進行溝通。
Kubernetes 的革新功能,除了將容器抽象化成應用程式的設計,還有其他設計,因為其他主流的大型管理平臺,比如說 AWS ECS,也有將容器抽象化為應用程式的設計,但是 Kubernetes Pod API,才是讓它擁有強大的生態系的關鍵差異。